home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / rayshade / graphtal.lzh / Graphtal.Amiga / Hull.C < prev    next >
C/C++ Source or Header  |  1992-11-17  |  3KB  |  120 lines

  1. /*
  2.  * Hull.C - methods for hull manipulations.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  *                     University of Berne, Switzerland
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified, and redistributed
  9.  * provided that this copyright notice is preserved on all copies.
  10.  *
  11.  * You may not distribute this software, in whole or in part, as part of
  12.  * any commercial product without the express consent of the authors.
  13.  *
  14.  * There is no warranty or other guarantee of fitness of this software
  15.  * for any purpose.  It is provided solely "as is".
  16.  *
  17.  */
  18.  
  19. #include <values.h>
  20. #include "Hull.h"
  21.  
  22. //___________________________________________________________ Hull
  23.  
  24. implementTable(HullSymtab, rcString, HullPtr);
  25.  
  26. Hull::Hull()
  27. : primitives(new GeoObjectList(10))
  28. {}
  29.  
  30. Hull::~Hull()
  31. {
  32. #ifndef OLD_STYLE_CPP
  33.   // AT&T 2.x has problems: too compilcated pointer expression
  34.   for (register long i=0; i<primitives->count(); i++)
  35.     delete primitives->item(i);
  36. #endif
  37.  
  38.   delete primitives;
  39. }
  40.  
  41. void Hull::addPrimitive(GeoObject* obj)
  42. {
  43.   primitives->append(obj);
  44. }
  45.  
  46. long Hull::numPrimitives() const
  47. {
  48.   return primitives->count();
  49. }
  50.  
  51. /*
  52.  * Intersect ray with hull primitives and calculate closest object
  53.  * and distance to this object.
  54.  * intersect return TRUE if hit occured, FALSE otherwise.
  55.  */
  56.  
  57. int Hull::intersect(const Ray& ray, real& dist, GeoObject*& obj) const
  58. {
  59.   int hit = FALSE;
  60.   TransMatrix* itrans;
  61.  
  62.   dist = MAXFLOAT;
  63.   obj = NULL;
  64.  
  65.   for (register long i=0; i<primitives->count(); i++) {
  66.  
  67.     /*
  68.      * primitive has transformation matrix attached 
  69.      *  -> transform the ray
  70.      */
  71.     if ((itrans = primitives->item(i)->getInvTrans()) != NULL) {
  72.       Ray newRay(ray);
  73.       real distfact = newRay.transform(*itrans);
  74.  
  75.       /*
  76.        * Transformimg the ray can change the distance between the
  77.        * ray origin and the Point of intersection. We save the amount
  78.        * the is "stretched" and later devide the computed distance
  79.        * by this amount.
  80.        */
  81.       dist *= distfact;
  82.       if (primitives->item(i)->intersect(newRay, EPSILON*distfact, dist)) {
  83.     obj = primitives->item(i);
  84.     hit = TRUE;
  85.       }
  86.       dist /= distfact;
  87.     }
  88.     else {
  89.       if (primitives->item(i)->intersect(ray, EPSILON, dist)) {
  90.     obj = primitives->item(i);
  91.     hit = TRUE;
  92.       }
  93.     }
  94.   }
  95.   return hit;
  96. }
  97.  
  98. /*
  99.  * convertToPolygonList tesselates all the primitives in the hull 
  100.  * and returns the result as a list of polygons.
  101.  * If there is no polygon in the hull, a empty polygon list is
  102.  * returned.
  103.  */
  104.  
  105. PolygonList* Hull::convertToPolygonList(const BoundingBox& bbox) const
  106. {
  107.   PolygonList* polys = new PolygonList;
  108.   PolygonList* polytmp;
  109.   
  110.   for (register long i=0; i<primitives->count(); i++) {
  111.     if ((polytmp = primitives->item(i)->tesselate(bbox)) != NULL) {
  112.       for (register long j=0; j<polytmp->count(); j++)
  113.     polys->append(polytmp->item(j));
  114.       delete polytmp;
  115.     }
  116.   }
  117.  
  118.   return polys;
  119. }
  120.